package com.aly.beanValidate.core;

import com.aly.beanValidate.core.validator.CheckValidators;
import com.aly.beanValidate.core.validator.Validatable;
import com.aly.beanValidate.core.validator.impl.ArrayValidator;
import com.aly.beanValidate.core.validator.impl.NotNullValidate;
import com.aly.beanValidate.i.BeanInfo;
import com.aly.beanValidate.i.FileInfo;
import com.aly.beanValidate.i.FileInfos;
import com.aly.game.util.StringUtils;
import org.dom4j.Element;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Stream;

public class FieldConfigs {
    private final List<Validatable> validators;
    private final FieldDefinition definition;
    private int useCount;

    FieldConfigs(FieldDefinition definition, Element element, GlobalConfigs globalConfigs) throws Exception {
        this.definition =definition;
        validators = new ArrayList<>();
        for (Element subElement : element.elements()) {
            Validatable validatable = CheckValidators.create(subElement, globalConfigs);
            validators.add(validatable);
        }
    }

    public FieldDefinition getDefinition() {
        return definition;
    }

    public int getUseCount() {
        return useCount;
    }


    StringBuffer validate(String val, BeanInfo bean, FileInfo fileInfo, FileInfos fileInfos) {
        useCount++;
        StringBuffer sb = new StringBuffer();

        if (StringUtils.isEmpty(val)) {
            validators.stream().filter(v -> v instanceof NotNullValidate)
                    .limit(1)
                    .forEach(v -> sb.append("配置数据为空"));
        } else {
            if (definition.isArray()) {
                String[] split = val.split(",");
                validators.stream()
                        .filter(v -> v instanceof ArrayValidator)
                        .forEach(v -> v.validate(sb, definition, split, bean, fileInfo, fileInfos));

                for (String s : split) {
                    StringBuffer msg = validateVal(definition, s, bean, fileInfo, fileInfos, v -> !(v instanceof ArrayValidator));
                    sb.append(msg);
                }
            } else {
                StringBuffer msg = validateVal(definition, val, bean, fileInfo, fileInfos, v -> !(v instanceof ArrayValidator));
                sb.append(msg);
            }
        }

        if (sb.length() > 0) {
            StringBuilder msg = new StringBuilder()
                    .append("字段验证失败:{name:").append(definition.getFieldName())
                    .append(",type:").append(definition.getBaseType())
                    .append(",val:").append(val)
                    .append("}-->");
            sb.insert(0, msg);
            return sb;
        }
        return null;
    }

    private StringBuffer validateVal(FieldDefinition fieldDefinition, String val, BeanInfo bean, FileInfo fileInfo, FileInfos fileInfos, Predicate<Validatable> filter) {
        StringBuffer sb = new StringBuffer();
        Object transferVal;
        try {
            transferVal = fieldDefinition.getBaseType().transfer(val);
        } catch (Throwable throwable) {
            sb.append("[").append(val).append("] 与定义类型不匹配");
            return sb;
        }
        if (null != transferVal) {
            Stream<Validatable> stream = validators.stream();
            if (null != filter) {
                stream = stream.filter(filter);
            }
            stream.forEach(v -> v.validate(sb, fieldDefinition, transferVal, bean, fileInfo, fileInfos));
        }
        return sb;
    }
}
